using System;
using Oracle.ManagedDataAccess.Client;
using OracleInternal.Common;
using OracleInternal.ConnectionPool;
using OracleInternal.ServiceObjects;

namespace OracleInternal.MTS
{
	internal class CCPMTSTxnBranch : MTSTxnBranch
	{
		internal CCPMTSTxnBranch(MTSTxnRM txnRM, int branchNum)
			: base(txnRM, branchNum)
		{
		}

		internal override OracleConnectionImpl GetConnection(bool bMustMatch, out bool bMatchFound)
		{
			OracleConnectionImpl oracleConnectionImpl = null;
			bMatchFound = false;
			try
			{
				oracleConnectionImpl = OracleConnectionDispenser<OraclePoolManager, OraclePool, OracleConnectionImpl>.GetEnlisted(m_connCreds, null, m_mtsTxnRM.m_serviceName, m_mtsTxnRM.m_pdbName, m_mtsTxnRM.m_sysTxn, m_dbInstance, m_branchNum, bMustMatch, out bMatchFound);
			}
			catch (Exception ex)
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.GetConnection, "MTSTxnBranch.GetConnection(): Get Exception in finding  a connection in  OracleConnectionDispenser.GetEnlisted()bMustMatch = " + bMustMatch + " bMatchFound = " + bMatchFound + "\t TxnID = " + m_xid);
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.GetConnection, OracleConnectionDispenser<OraclePoolManager, OraclePool, OracleConnectionImpl>.Dump());
				}
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.GetConnection, ex);
				throw;
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					if (oracleConnectionImpl != null)
					{
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.GetConnection, "MTSTxnBranch.GetConnection(bMustMatch = " + bMustMatch + ", bMatchFound = " + bMatchFound + "): Get a Connection with Conn ID = " + oracleConnectionImpl.m_endUserSessionId + " to DBInst = " + oracleConnectionImpl.m_instanceName + "\t TxnID = " + m_xid);
					}
					else
					{
						Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.GetConnection, "MTSTxnBranch.GetConnection(bMustMatch = " + bMustMatch + ", bMatchFound = " + bMatchFound + "): Cannot find a Connection. \t TxnID = " + m_xid);
					}
				}
			}
			return oracleConnectionImpl;
		}

		internal override void ReleaseConnection(string txnOperation, OracleConnectionImpl connImpl, TransXID txnXID)
		{
			if (ProviderConfig.m_bTraceLevelPrivate)
			{
				Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4352, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.ReleaseConnection, txnOperation + ": Releasing Conn ID = " + connImpl.m_endUserSessionId + " to DBInst = " + connImpl.m_instanceName + "\t TxnID = " + txnXID?.ToString() + "\t Local Txn id = " + m_txnLocalID);
			}
			try
			{
				OracleConnectionDispenser<OraclePoolManager, OraclePool, OracleConnectionImpl>.PutFromDTC(connImpl);
			}
			catch (Exception ex)
			{
				OracleException.HandleError(OracleTraceLevel.Private, (OracleTraceTag)6144, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.ReleaseConnection, ex);
			}
			finally
			{
				if (ProviderConfig.m_bTraceLevelPrivate)
				{
					Trace.Write(OracleTraceLevel.Private, (OracleTraceTag)4608, OracleTraceClassName.CCPMTSTxnBranch, OracleTraceFuncName.ReleaseConnection, txnOperation + ": Releasing Conn ID = " + connImpl.m_endUserSessionId + " to DBInst = " + connImpl.m_instanceName + "\t TxnID = " + txnXID?.ToString() + "\t Local Txn ID = " + m_txnLocalID);
				}
			}
		}

		internal override bool CanResetConnection(bool bMatchConn, TxnBranchState branchState)
		{
			return bMatchConn;
		}
	}
}
